# import stimuli information
df.stimuli =
read_csv(paste0(stim_dir,
"fun-puzzles-exp1/production2_puzzles-test.csv"))
df.stimuli %>%
head()## # A tibble: 6 × 15
## puzzle_id collection_name level_name layout level_width level_height
## <dbl> <chr> <dbl> <chr> <dbl> <dbl>
## 1 0 Microban 67 ['###… 7 8
## 2 1 Microban 33 ['###… 7 7
## 3 2 Microban 26 [' ##… 6 8
## 4 3 Sokogen-990602… 13 ['###… 8 6
## 5 4 Sokogen-990602… 19 ['###… 6 6
## 6 5 Sokogen-990602… 41 ['###… 9 7
## # ℹ 9 more variables: sokobanonline__likes_rate <dbl>,
## # sokobanonline__solve_rate <dbl>,
## # sokobanonline__shortest_solution <dbl>, enjoyment_cat <chr>,
## # difficulty_cat <chr>, shortestPath_cat <chr>, stimuli_set <chr>,
## # boxes <chr>, start_position <chr>
## # A tibble: 6 × 20
## puzzle_id collection_name level_name layout level_width level_height
## <dbl> <chr> <dbl> <chr> <dbl> <dbl>
## 1 0 Microban 67 ['###… 7 8
## 2 1 Microban 33 ['###… 7 7
## 3 2 Microban 26 [' ##… 6 8
## 4 3 Sokogen-990602… 13 ['###… 8 6
## 5 4 Sokogen-990602… 19 ['###… 6 6
## 6 5 Sokogen-990602… 41 ['###… 9 7
## # ℹ 14 more variables: sokobanonline__likes_rate <dbl>,
## # sokobanonline__solve_rate <dbl>,
## # sokobanonline__shortest_solution <dbl>, enjoyment_cat <chr>,
## # difficulty_cat <chr>, shortestpath_cat <chr>, stimuli_set <chr>,
## # boxes <chr>, start_position <chr>, shortest_solution <dbl>,
## # astar_solution <chr>, astar_iters <dbl>,
## # astar_solution_length <dbl>, astar_solution_string <chr>
df.exclusions =
read_csv(paste0(data_dir,
"fun-puzzles-exp1/production2_exclusions.csv"))
df.exclusions %>%
count(reasons)## # A tibble: 10 × 2
## reasons n
## <chr> <int>
## 1 Failed comprehension 2
## 2 Only 1 practice trials 1
## 3 Only 2 practice trials 5
## 4 bad trace log 38
## 5 comparison: only 7 posttest trials 2
## 6 comparison: only 7 pretest trials 4
## 7 empty trace log 12
## 8 test attempts: only 7 trials with trace data 6
## 9 test ratings: only 6 trials 1
## 10 test ratings: only 7 trials 15
df.survey =
read_csv(paste0(data_dir,
"fun-puzzles-exp1/production2_survey.csv"))
df.survey_processed =
df.survey %>%
# mutate scales to show labels
mutate(judgedDifficulty = factor(judgedDifficulty,
levels = c(1, 2, 3, 4, 5),
labels = c("1\nVery Easy", "2", "3", "4", "5\nVery Hard")),
participantEffort = factor(participantEffort,
levels = c(1, 2, 3, 4, 5),
labels = c("1\nVery Low", "2", "3", "4", "5\nVery High")),
sokobanFamiliarity = factor(sokobanFamiliarity,
levels = c(0, 1, 2, 3),
labels = c("Never", "A few times", "Several times", "Very familiar")),
gamingFrequency = factor(gamingFrequency,
levels = c(0, 1, 2, 3, 4),
labels = c("None", "< 1h", "1-5h", "6-10h", "> 10h"))) %>%
# filter out exclusions
filter(!gameID %in% df.exclusions$gameID)
df.survey_processed %>%
head()## # A tibble: 6 × 27
## project experiment iteration stim_id gameID condition
## <chr> <chr> <chr> <chr> <chr> <chr>
## 1 fun-puzzles fun-puzzles-exp1 production2 6790956f9… 3940-… difficult
## 2 fun-puzzles fun-puzzles-exp1 production2 6790956f9… 7209-… difficult
## 3 fun-puzzles fun-puzzles-exp1 production2 6790956f9… 4733-… difficult
## 4 fun-puzzles fun-puzzles-exp1 production2 6790956f9… 6110-… difficult
## 5 fun-puzzles fun-puzzles-exp1 production2 6790956f9… 0047-… difficult
## 6 fun-puzzles fun-puzzles-exp1 production2 6790956f9… 2839-… difficult
## # ℹ 21 more variables: startInstructionTS <dbl>,
## # startPracticeTS <dbl>, startPreTS <dbl>, startMainTS <dbl>,
## # startPostTS <dbl>, startSurveyTS <dbl>,
## # startComprehensionTS <dbl>, endExperimentTS <dbl>,
## # participantExplanations <chr>, judgedDifficulty <fct>,
## # participantEffort <fct>, sokobanFamiliarity <fct>,
## # gamingFrequency <fct>, participantYears <dbl>, …
8 test trials:
df.game =
read_csv(paste0(data_dir,
"/fun-puzzles-exp1/production2_testTrials.csv"))
df.game_processed =
df.game %>%
# filter out exclusions
filter(!gameID %in% df.exclusions$gameID) %>%
# complement puzzle ids
mutate(puzzle_id = paste(str_sub(collection_name, 1, 7), level_name)) %>%
# rename cols
rename(rating = rate_response,
ratingRT = rate_rt)
df.game_processed %>%
head()## # A tibble: 6 × 32
## project experiment iteration stim_id gameID condition study_phase
## <chr> <chr> <chr> <chr> <chr> <chr> <chr>
## 1 fun-puzzl… fun-puzzl… producti… 679095… 3940-… difficult test
## 2 fun-puzzl… fun-puzzl… producti… 679095… 3940-… difficult test
## 3 fun-puzzl… fun-puzzl… producti… 679095… 3940-… difficult test
## 4 fun-puzzl… fun-puzzl… producti… 679095… 3940-… difficult test
## 5 fun-puzzl… fun-puzzl… producti… 679095… 3940-… difficult test
## 6 fun-puzzl… fun-puzzl… producti… 679095… 3940-… difficult test
## # ℹ 25 more variables: trialNum <dbl>, stimuli_set <chr>,
## # author_name <chr>, collection_name <chr>, level_name <dbl>,
## # width <dbl>, height <dbl>, layout <chr>, boxes <chr>,
## # start_position.x <dbl>, start_position.y <dbl>,
## # select_response <dbl>, select_rt <dbl>, rating <dbl>,
## # ratingRT <dbl>, solveDuration <dbl>, solved <dbl>,
## # boxesSolved <dbl>, attempt_nInputEvents <dbl>, …
# calculate summary ratings
df.summary_ratings =
df.game_processed %>%
# bootstrap ci
group_by(stimuli_set, puzzle_id, condition) %>%
tidyboot_mean(rating, na.rm = T) %>%
ungroup() %>%
# median, sd, etc.
left_join(summarizer(df.game_processed, target_cols = c(rating),
puzzle_id, condition) %>%
dplyr::select(-ends_with('mean')),
by = c("puzzle_id", "condition")) %>%
rename(rating_meanBoot = empirical_stat,
rating_mean = mean,
rating_ciLo = ci_lower,
rating_ciHi = ci_upper)
df.summary_ratings %>%
head()## # A tibble: 6 × 10
## stimuli_set puzzle_id condition n rating_meanBoot rating_ciLo
## <chr> <chr> <chr> <int> <dbl> <dbl>
## 1 A Microba 104 difficult 36 9.08 8.51
## 2 A Microba 104 enjoyable 32 4.28 3.41
## 3 A Microba 67 difficult 36 8.67 8
## 4 A Microba 67 enjoyable 32 4.03 3.23
## 5 A Sokogen 13 difficult 36 7.25 6.29
## 6 A Sokogen 13 enjoyable 32 5.59 4.57
## # ℹ 4 more variables: rating_mean <dbl>, rating_ciHi <dbl>,
## # rating_median <dbl>, rating_sd <dbl>
# add avg ratings to game data df
df.game_processed =
df.game_processed %>%
left_join(df.summary_ratings %>%
dplyr::select(condition, puzzle_id, rating_mean) %>%
pivot_wider(names_from = condition, values_from = rating_mean)) %>%
rename(mean_difficult = difficult,
mean_enjoyable = enjoyable) %>%
mutate(puzzle_id_sorted = reorder(puzzle_id, mean_difficult))16 comparison trials:
df.comparison =
read_csv(paste0(data_dir,
"fun-puzzles-exp1/production2_compareTrials.csv"))
df.comparison_processed =
df.comparison %>%
# filter out exclustions
filter(!gameID %in% df.exclusions$gameID) %>%
# keep only relevant cols
dplyr::select(gameID:level_name_1) %>%
# add phase and puzzle info
mutate(study_phase = factor(study_phase,
levels = c("pretest", "posttest")),
puzzle_id_0 = paste(str_sub(collection_name_0, 1, 7),
level_name_0),
puzzle_id_1 = paste(str_sub(collection_name_1, 1, 7),
level_name_1)) %>%
# keep only relevant cols
dplyr::select(-c(collection_name_0:level_name_1)) %>%
# compute response times
mutate(rt_done2 = rt_done2 - rt_done1,
rt_choose = rt - rt_done2)
df.comparison_processed %>%
head()## # A tibble: 6 × 13
## gameID condition stim_id study_phase trial_type trialNum response
## <chr> <chr> <chr> <fct> <chr> <dbl> <dbl>
## 1 3940-a6a… difficult 679095… pretest sokoban-c… 1 0
## 2 3940-a6a… difficult 679095… pretest sokoban-c… 2 0
## 3 3940-a6a… difficult 679095… pretest sokoban-c… 3 1
## 4 3940-a6a… difficult 679095… pretest sokoban-c… 4 0
## 5 3940-a6a… difficult 679095… pretest sokoban-c… 5 0
## 6 3940-a6a… difficult 679095… pretest sokoban-c… 6 1
## # ℹ 6 more variables: rt <dbl>, rt_done1 <dbl>, rt_done2 <dbl>,
## # puzzle_id_0 <chr>, puzzle_id_1 <chr>, rt_choose <dbl>
Create dataset containing all relevant information at once:
df.analysis =
df.game_processed %>%
left_join(df.survey_processed %>%
dplyr::select(gameID,
judgedDifficulty,
participantEffort,
sokobanFamiliarity),
by = "gameID") %>%
left_join(df.metadata %>%
dplyr::select(puzzle_id_num = puzzle_id,
layout,
sokobanonline__solve_rate,
astar_iters, astar_solution_length),
by = "layout") %>%
left_join(df.survey_processed %>%
dplyr::select(gameID,
age = participantYears,
gender = participantGender),
by = "gameID") %>%
mutate(judgedDifficulty = as.numeric(judgedDifficulty),
sokobanFamiliarity = as.numeric(sokobanFamiliarity),
participantEffort = as.numeric(participantEffort)) %>%
dplyr::select(subject_id = gameID,
age, gender,
puzzle_id_sorted, puzzle_id_num,
trialNum, stimuli_set,
layout,
select_response, rating,
solveDuration, solved, boxesSolved,
attempt_nInputEvents, attempt_nRestart, attempt_nUndo,
sokobanonline__solve_rate, astar_iters, astar_solution_length,
judgedDifficulty, mean_difficult,
participantEffort, mean_enjoyable,
sokobanFamiliarity)
df.analysis %>%
head()## # A tibble: 6 × 24
## subject_id age gender puzzle_id_sorted puzzle_id_num trialNum
## <chr> <dbl> <chr> <fct> <dbl> <dbl>
## 1 3940-a6a959f6-… 23 Female Microba 67 0 1
## 2 3940-a6a959f6-… 23 Female Sokogen 13 3 2
## 3 3940-a6a959f6-… 23 Female Sokogen 32 6 3
## 4 3940-a6a959f6-… 23 Female Sokogen 18 9 4
## 5 3940-a6a959f6-… 23 Female Microba 104 12 5
## 6 3940-a6a959f6-… 23 Female Sokogen 38 15 6
## # ℹ 18 more variables: stimuli_set <chr>, layout <chr>,
## # select_response <dbl>, rating <dbl>, solveDuration <dbl>,
## # solved <dbl>, boxesSolved <dbl>, attempt_nInputEvents <dbl>,
## # attempt_nRestart <dbl>, attempt_nUndo <dbl>,
## # sokobanonline__solve_rate <dbl>, astar_iters <dbl>,
## # astar_solution_length <dbl>, judgedDifficulty <dbl>,
## # mean_difficult <dbl>, participantEffort <dbl>, …
Age by condition:
## # A tibble: 1 × 5
## n M SD min max
## <int> <dbl> <dbl> <dbl> <dbl>
## 1 1640 36.7 12.3 18 74
Gender:
## # A tibble: 4 × 2
## gender n
## <chr> <int>
## 1 Female 696
## 2 Male 912
## 3 Non-binary 24
## 4 Prefer not to answer 8
df.analysis %>%
group_by(puzzle_id_sorted) %>%
summarise(n = n(),
M = mean(solved),
SD = sd(solved),
min = min(solved),
max = max(solved)) %>%
arrange(desc(M))## # A tibble: 24 × 6
## puzzle_id_sorted n M SD min max
## <fct> <int> <dbl> <dbl> <dbl> <dbl>
## 1 Dimitri 37 67 0.806 0.398 0 1
## 2 Sokogen 17 67 0.776 0.420 0 1
## 3 Microba 48 67 0.731 0.447 0 1
## 4 Microba 43 70 0.671 0.473 0 1
## 5 Sokogen 14 70 0.671 0.473 0 1
## 6 Sokogen 6 67 0.627 0.487 0 1
## 7 Microba 41 67 0.567 0.499 0 1
## 8 Sokogen 32 68 0.5 0.504 0 1
## 9 Sokogen 13 68 0.471 0.503 0 1
## 10 Microba 26 70 0.443 0.500 0 1
## # ℹ 14 more rows
df.analysis %>%
filter(!is.na(solved)) %>%
mutate(puzzle_id_sorted = fct_reorder(puzzle_id_sorted,
solved,
.fun = mean, .na_rm = TRUE)) %>%
group_by(puzzle_id_sorted) %>%
filter(n() > 0) %>%
ungroup() %>%
ggplot(aes(x = factor(puzzle_id_sorted),
y = (solved)*100,
fill = stimuli_set)) +
stat_summary(fun = mean,
geom = "bar",
width = 0.6) +
stat_summary(fun.data = mean_cl_boot,
geom = "errorbar",
width = 0.2) +
scale_y_continuous(limits = c(0, 100),
breaks = seq(0, 100, 25)) +
labs(x = "Puzzle name",
y = "% solved",
title = "% solved per puzzle",
subtitle = "N = 205 subjects, 24 puzzles total (n = 67-70 each)",
fill = "Puzzle block") +
coord_flip()df.analysis %>%
group_by(puzzle_id_sorted, solved) %>%
summarise(n = n(),
M = mean(boxesSolved),
SD = sd(boxesSolved),
min = min(boxesSolved),
max = max(boxesSolved)) %>%
arrange(desc(M))## # A tibble: 47 × 7
## # Groups: puzzle_id_sorted [24]
## puzzle_id_sorted solved n M SD min max
## <fct> <dbl> <int> <dbl> <dbl> <dbl> <dbl>
## 1 Microba 43 1 47 3 0 3 3
## 2 Dimitri 37 1 54 3 0 3 3
## 3 Microba 48 1 49 3 0 3 3
## 4 Sokogen 14 1 47 3 0 3 3
## 5 Sokogen 17 1 52 3 0 3 3
## 6 Sokogen 6 1 42 3 0 3 3
## 7 Sokogen 32 1 34 3 0 3 3
## 8 Microba 26 1 31 3 0 3 3
## 9 Microba 17 1 25 3 0 3 3
## 10 Microba 41 1 38 3 0 3 3
## # ℹ 37 more rows
df.analysis %>%
filter(!is.na(solved)) %>%
mutate(puzzle_id_sorted = fct_reorder(puzzle_id_sorted,
solved,
.fun = mean, .na_rm = TRUE)) %>%
group_by(puzzle_id_sorted) %>%
filter(n() > 0) %>%
ungroup() %>%
ggplot(aes(x = factor(puzzle_id_sorted),
y = boxesSolved)) +
stat_summary(fun.data = mean_cl_boot,
geom = "pointrange",
width = 0.2,
aes(color = stimuli_set)) +
geom_point(position = position_jitter(height = .05,
width = 0.1),
alpha = .05,
size = 2,
show.legend = FALSE) +
scale_y_continuous(limits = c(0, 3),
breaks = seq(0, 3, 1)) +
labs(x = "Puzzle name",
y = "# of boxes solved",
title = "Number of boxes solved per puzzle (out of 3)",
subtitle = "N = 205 subjects, 24 puzzles total (n = 67-70 each)",
color = "Puzzle block") +
coord_flip()df.analysis %>%
group_by(puzzle_id_sorted) %>%
summarise(n = n(),
M = mean(attempt_nInputEvents),
SD = sd(attempt_nInputEvents),
min = min(attempt_nInputEvents),
max = max(attempt_nInputEvents)) %>%
arrange(desc(M))## # A tibble: 24 × 6
## puzzle_id_sorted n M SD min max
## <fct> <int> <dbl> <dbl> <dbl> <dbl>
## 1 Microba 33 67 265. 129. 43 622
## 2 Sokogen 40 70 236. 139. 22 614
## 3 Microba 104 68 228. 144. 10 608
## 4 Microba 67 68 224. 110. 23 473
## 5 Sokogen 41 70 211. 121. 8 537
## 6 Sokogen 46 70 209. 121. 17 511
## 7 Sokogen 38 68 198. 109. 12 475
## 8 Sokogen 39 67 195. 109. 34 429
## 9 Sokogen 19 67 192. 105. 28 558
## 10 Microba 26 70 190. 126. 23 548
## # ℹ 14 more rows
df.analysis %>%
filter(!is.na(solved)) %>%
mutate(puzzle_id_sorted = fct_reorder(puzzle_id_sorted,
solved,
.fun = mean, .na_rm = TRUE)) %>%
group_by(puzzle_id_sorted) %>%
filter(n() > 0) %>%
ungroup() %>%
ggplot(aes(x = factor(puzzle_id_sorted),
y = attempt_nInputEvents)) +
stat_summary(fun.data = mean_cl_boot,
geom = "pointrange",
width = 0.2,
aes(color = stimuli_set)) +
geom_point(position = position_jitter(height = .05,
width = .1),
alpha = .05,
size = 2,
show.legend = FALSE) +
scale_y_continuous(limits = c(0, 600),
breaks = seq(0, 600, 50)) +
labs(x = "Puzzle name",
y = "# of moves attempted",
title = "Number of moves attempted per puzzle",
subtitle = "N = 205 subjects, 24 puzzles total (n = 67-70 each)",
color = "Puzzle block") +
coord_flip()df.analysis %>%
group_by(puzzle_id_sorted) %>%
summarise(n = n(),
M = mean(solveDuration, na.rm = T),
SD = sd(solveDuration, na.rm = T),
min = min(solveDuration, na.rm = T),
max = max(solveDuration, na.rm = T)) %>%
arrange(desc(M))## # A tibble: 24 × 6
## puzzle_id_sorted n M SD min max
## <fct> <int> <dbl> <dbl> <dbl> <dbl>
## 1 Sokogen 46 70 248. 51.7 160 300
## 2 Microba 104 68 212. 57.5 156 280
## 3 Sokogen 35 68 204. 62.4 82 276
## 4 Sokogen 34 68 197. 58.4 103 299
## 5 Sokogen 40 70 191. 97.8 104 297
## 6 Microba 33 67 191. 82.8 39 295
## 7 Microba 41 67 185. 68.6 63 293
## 8 Sokogen 41 70 184. 64.7 95 297
## 9 Sokogen 39 67 182. 70.1 82 288
## 10 Sokogen 38 68 167. 58.6 81 221
## # ℹ 14 more rows
df.analysis %>%
filter(!is.na(solved)) %>%
mutate(puzzle_id_sorted = fct_reorder(puzzle_id_sorted,
solved,
.fun = mean, .na_rm = TRUE)) %>%
group_by(puzzle_id_sorted) %>%
filter(n() > 0) %>%
ungroup() %>%
ggplot(aes(x = factor(puzzle_id_sorted),
y = solveDuration)) +
stat_summary(fun.data = mean_cl_boot,
geom = "pointrange",
width = 0.2,
aes(color = stimuli_set)) +
geom_point(position = position_jitter(height = .05,
width = .1),
size = 2,
alpha = .05,
show.legend = FALSE) +
scale_y_continuous(limits = c(0, 300),
breaks = seq(0, 300, 60)) +
labs(x = "Puzzle name",
y = "Time until solution (in sec)",
title = "Time until solution per puzzle",
subtitle = "N = 205 subjects, 24 puzzles total (n = 67-70 each)",
color = "Puzzle block") +
coord_flip()Do people generally become better at Sokoban over time?
I.e., do we see differences in performance metrics (% solved, boxes solved, time until solution, number of steps) when we compare the first four puzzles people solved, vs the last four puzzles people solved?
df.analysis %>%
mutate(trialNum = case_when(trialNum > 4 ~ "Last half of puzzles",
trialNum <= 4 ~ "First half of puzzles"),
puzzle_id_sorted = fct_reorder(puzzle_id_sorted,
solved,
.fun = mean, .na_rm = TRUE)) %>%
filter(!is.na(trialNum)) %>%
ggplot(aes(x = puzzle_id_sorted,
y = (solved)*100,
fill = trialNum)) +
stat_summary(fun = mean,
geom = "bar",
width = .6,
position = position_dodge(.8)) +
stat_summary(fun.data = mean_cl_boot,
geom = "errorbar",
position = position_dodge(.8)) +
scale_y_continuous(limits = c(0, 100),
breaks = seq(0, 100, 25)) +
labs(x = "Puzzle Name",
y = "% solved",
title = "% solved over time (first vs last half of puzzle set)",
subtitle = "8 puzzles per set",
fill = "Stage") +
coord_flip()Do we see a progression in % solved when we break it down by puzzle order?
df.analysis %>%
group_by(trialNum, puzzle_id_sorted) %>%
summarise(mean = mean(solved)) %>%
ggplot(aes(x = trialNum,
y = (mean*100),
color = puzzle_id_sorted)) +
geom_point(position = position_jitter(width = .1,
height = .1),
size = 2,
alpha = .4) +
labs(x = "Puzzle order (1 through 8)",
y = "% solved",
title = "% solved over time",
fill = "Puzzle") +
theme(legend.position = "none") +
scale_x_continuous(breaks = seq(1,8,1))Fitting the mixed effects model:
# mixed effects model
lm.pct_solved_order =
glmer(solved ~
1 +
# fixed effect for puzzle order
trialNum +
# controlling for other variables
sokobanonline__solve_rate + # difficulty
participantEffort + # subjective effort
attempt_nRestart + # no of attempts
mean_enjoyable + # sampled enjoyment ratings
# random intercept for player
(1 | subject_id),
family = binomial(link = "logit"),
data = df.analysis)
# summary
lm.pct_solved_order %>%
summary()## Generalized linear mixed model fit by maximum likelihood (Laplace
## Approximation) [glmerMod]
## Family: binomial ( logit )
## Formula:
## solved ~ 1 + trialNum + sokobanonline__solve_rate + participantEffort +
## attempt_nRestart + mean_enjoyable + (1 | subject_id)
## Data: df.analysis
##
## AIC BIC logLik deviance df.resid
## 1280.9 1318.7 -633.5 1266.9 1633
##
## Scaled residuals:
## Min 1Q Median 3Q Max
## -7.4776 -0.2921 -0.1021 0.2233 14.9158
##
## Random effects:
## Groups Name Variance Std.Dev.
## subject_id (Intercept) 5.921 2.433
## Number of obs: 1640, groups: subject_id, 205
##
## Fixed effects:
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) -4.77692 2.05322 -2.327 0.020 *
## trialNum -0.16298 0.03925 -4.153 3.29e-05 ***
## sokobanonline__solve_rate 0.82759 1.38413 0.598 0.550
## participantEffort -0.19478 0.37544 -0.519 0.604
## attempt_nRestart -0.59827 0.05025 -11.905 < 2e-16 ***
## mean_enjoyable 1.21227 0.10574 11.464 < 2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Correlation of Fixed Effects:
## (Intr) trilNm skb___ prtcpE attm_R
## trialNum -0.034
## skbnnln__s_ -0.363 -0.183
## prtcpntEffr -0.889 0.031 0.012
## attmpt_nRst -0.098 0.224 0.017 0.060
## mean_enjybl -0.061 -0.004 -0.441 -0.009 -0.176
## optimizer (Nelder_Mead) convergence code: 0 (OK)
## Model failed to converge with max|grad| = 0.00203212 (tol = 0.002, component 1)
## $trialNum
## # Predicted probabilities of solved
##
## trialNum | Predicted | 95% CI
## ---------------------------------
## 1 | 0.45 | 0.46, 0.51
## 2 | 0.43 | 0.45, 0.51
## 3 | 0.40 | 0.45, 0.50
## 4 | 0.38 | 0.43, 0.50
## 5 | 0.35 | 0.42, 0.49
## 6 | 0.32 | 0.40, 0.48
## 7 | 0.29 | 0.37, 0.48
## 8 | 0.27 | 0.34, 0.47
##
## Adjusted for:
## * sokobanonline__solve_rate = 0.73
## * participantEffort = 4.80
## * attempt_nRestart = 3.76
## * mean_enjoyable = 5.57
## * subject_id = 0 (population-level)
##
## $sokobanonline__solve_rate
## # Predicted probabilities of solved
##
## sokobanonline__solve_rate | Predicted | 95% CI
## --------------------------------------------------
## 0.40 | 0.32 | 0.30, 0.51
## 0.60 | 0.35 | 0.40, 0.50
## 0.80 | 0.38 | 0.43, 0.50
## 1.00 | 0.40 | 0.39, 0.52
##
## Adjusted for:
## * trialNum = 4.50
## * participantEffort = 4.80
## * attempt_nRestart = 3.76
## * mean_enjoyable = 5.57
## * subject_id = 0 (population-level)
##
## $participantEffort
## # Predicted probabilities of solved
##
## participantEffort | Predicted | 95% CI
## ------------------------------------------
## 1 | 0.46 | 0.12, 0.85
## 3 | 0.42 | 0.30, 0.59
## 4 | 0.39 | 0.40, 0.51
## 5 | 0.36 | 0.42, 0.49
##
## Adjusted for:
## * trialNum = 4.50
## * sokobanonline__solve_rate = 0.73
## * attempt_nRestart = 3.76
## * mean_enjoyable = 5.57
## * subject_id = 0 (population-level)
##
## $attempt_nRestart
## # Predicted probabilities of solved
##
## attempt_nRestart | Predicted | 95% CI
## -----------------------------------------
## 0 | 0.57 | 0.49, 0.55
## 3 | 0.43 | 0.46, 0.50
## 6 | 0.15 | 0.22, 0.38
## 9 | 0.03 | 0.04, 0.13
## 11 | 0.01 | 0.01, 0.05
## 14 | 0.00 | 0.00, 0.01
## 17 | 0.00 | 0.00, 0.00
## 23 | 0.00 | 0.00, 0.00
##
## Adjusted for:
## * trialNum = 4.50
## * sokobanonline__solve_rate = 0.73
## * participantEffort = 4.80
## * mean_enjoyable = 5.57
## * subject_id = 0 (population-level)
##
## $mean_enjoyable
## # Predicted probabilities of solved
##
## mean_enjoyable | Predicted | 95% CI
## ---------------------------------------
## 3.50 | 0.05 | 0.08, 0.20
## 4.00 | 0.09 | 0.14, 0.29
## 4.50 | 0.16 | 0.23, 0.38
## 5.00 | 0.25 | 0.33, 0.45
## 6.00 | 0.44 | 0.46, 0.51
## 6.50 | 0.49 | 0.48, 0.52
## 7.00 | 0.52 | 0.48, 0.53
## 8.00 | 0.68 | 0.51, 0.63
##
## Adjusted for:
## * trialNum = 4.50
## * sokobanonline__solve_rate = 0.73
## * participantEffort = 4.80
## * attempt_nRestart = 3.76
## * subject_id = 0 (population-level)
##
## attr(,"class")
## [1] "ggalleffects" "list"
## attr(,"model.name")
## [1] "."
df.analysis %>%
mutate(trialNum = case_when(trialNum > 4 ~ "Last half of puzzles",
trialNum <= 4 ~ "First half of puzzles"),
puzzle_id_sorted = fct_reorder(puzzle_id_sorted,
solved,
.fun = mean, .na_rm = TRUE)) %>%
filter(!is.na(trialNum)) %>%
ggplot(aes(x = puzzle_id_sorted,
y = boxesSolved,
color = trialNum)) +
stat_summary(fun.data = mean_cl_boot,
geom = "pointrange",
position = position_dodge(.8)) +
geom_point(position = position_jitter(width = .1,
height = .1),
size = 2,
alpha = .1) +
scale_y_continuous(limits = c(0, 3),
breaks = seq(0,3,1)) +
labs(x = "Puzzle name",
y = "# of boxes solved (0-3)",
title = "# of boxes solved over time (first vs last half of puzzle set)",
subtitle = "8 puzzles per set",
color = "Stage") +
coord_flip()When broken down by individual puzzle:
df.analysis %>%
group_by(trialNum, puzzle_id_sorted) %>%
summarise(mean = mean(boxesSolved)) %>%
ggplot(aes(x = trialNum,
y = mean,
color = puzzle_id_sorted)) +
geom_point(position = position_jitter(width = .1,
height = .1),
size = 2,
alpha = .4) +
labs(x = "Puzzle order (1 through 8)",
y = "Mean # of boxes solved",
title = "Mean # of boxes solved over time",
fill = "Puzzle") +
theme(legend.position = "none") +
scale_x_continuous(breaks = seq(1,8,1)) +
scale_y_continuous(limits = c(0,3),
breaks = seq(0,3,1))Fitting the mixed effects model:
# mixed effects model
lm.number_solved_order =
glmer(boxesSolved ~
1 +
# fixed effect for puzzle order (controlling for difficulty)
trialNum +
# controlling for other variables
sokobanonline__solve_rate + # difficulty
participantEffort + # subjective effort
attempt_nRestart + # no of attempts
mean_enjoyable + # sampled enjoyment ratings
# random intercept for player
(1 | subject_id),
family = poisson(link = "log"),
data = df.analysis)
# summary
lm.number_solved_order %>%
summary()## Generalized linear mixed model fit by maximum likelihood (Laplace
## Approximation) [glmerMod]
## Family: poisson ( log )
## Formula:
## boxesSolved ~ 1 + trialNum + sokobanonline__solve_rate + participantEffort +
## attempt_nRestart + mean_enjoyable + (1 | subject_id)
## Data: df.analysis
##
## AIC BIC logLik deviance df.resid
## 4749.4 4787.2 -2367.7 4735.4 1633
##
## Scaled residuals:
## Min 1Q Median 3Q Max
## -1.6507 -0.3346 0.1122 0.2824 1.1029
##
## Random effects:
## Groups Name Variance Std.Dev.
## subject_id (Intercept) 0 0
## Number of obs: 1640, groups: subject_id, 205
##
## Fixed effects:
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) 0.285440 0.239226 1.193 0.23280
## trialNum -0.017090 0.007604 -2.248 0.02460 *
## sokobanonline__solve_rate -0.059276 0.264522 -0.224 0.82269
## participantEffort -0.005799 0.033906 -0.171 0.86421
## attempt_nRestart -0.016475 0.005364 -3.071 0.00213 **
## mean_enjoyable 0.116786 0.015963 7.316 2.55e-13 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Correlation of Fixed Effects:
## (Intr) trilNm skb___ prtcpE attm_R
## trialNum -0.079
## skbnnln__s_ -0.611 -0.119
## prtcpntEffr -0.705 0.004 0.026
## attmpt_nRst -0.268 0.092 0.032 0.094
## mean_enjybl 0.039 0.066 -0.540 -0.016 0.228
## optimizer (Nelder_Mead) convergence code: 0 (OK)
## boundary (singular) fit: see help('isSingular')
## $trialNum
## # Predicted counts of boxesSolved
##
## trialNum | Predicted | 95% CI
## ---------------------------------
## 1 | 2.19 | 2.06, 2.33
## 2 | 2.16 | 2.05, 2.27
## 3 | 2.12 | 2.04, 2.21
## 4 | 2.08 | 2.01, 2.16
## 5 | 2.05 | 1.98, 2.12
## 6 | 2.01 | 1.93, 2.10
## 7 | 1.98 | 1.88, 2.08
## 8 | 1.95 | 1.83, 2.07
##
## Adjusted for:
## * sokobanonline__solve_rate = 0.73
## * participantEffort = 4.80
## * attempt_nRestart = 3.76
## * mean_enjoyable = 5.57
## * subject_id = 0 (population-level)
##
## $sokobanonline__solve_rate
## # Predicted counts of boxesSolved
##
## sokobanonline__solve_rate | Predicted | 95% CI
## --------------------------------------------------
## 0.40 | 2.11 | 1.77, 2.51
## 0.60 | 2.08 | 1.93, 2.25
## 0.80 | 2.06 | 1.96, 2.16
## 1.00 | 2.03 | 1.76, 2.35
##
## Adjusted for:
## * trialNum = 4.50
## * participantEffort = 4.80
## * attempt_nRestart = 3.76
## * mean_enjoyable = 5.57
## * subject_id = 0 (population-level)
##
## $participantEffort
## # Predicted counts of boxesSolved
##
## participantEffort | Predicted | 95% CI
## ------------------------------------------
## 1 | 2.11 | 1.64, 2.73
## 3 | 2.09 | 1.84, 2.36
## 4 | 2.08 | 1.95, 2.21
## 5 | 2.06 | 1.99, 2.14
##
## Adjusted for:
## * trialNum = 4.50
## * sokobanonline__solve_rate = 0.73
## * attempt_nRestart = 3.76
## * mean_enjoyable = 5.57
## * subject_id = 0 (population-level)
##
## $attempt_nRestart
## # Predicted counts of boxesSolved
##
## attempt_nRestart | Predicted | 95% CI
## -----------------------------------------
## 0 | 2.20 | 2.09, 2.31
## 3 | 2.09 | 2.02, 2.17
## 6 | 1.99 | 1.91, 2.08
## 9 | 1.89 | 1.77, 2.02
## 11 | 1.83 | 1.68, 2.00
## 14 | 1.75 | 1.56, 1.96
## 17 | 1.66 | 1.44, 1.92
## 23 | 1.50 | 1.22, 1.85
##
## Adjusted for:
## * trialNum = 4.50
## * sokobanonline__solve_rate = 0.73
## * participantEffort = 4.80
## * mean_enjoyable = 5.57
## * subject_id = 0 (population-level)
##
## $mean_enjoyable
## # Predicted counts of boxesSolved
##
## mean_enjoyable | Predicted | 95% CI
## ---------------------------------------
## 3.50 | 1.62 | 1.50, 1.75
## 4.00 | 1.72 | 1.62, 1.83
## 4.50 | 1.82 | 1.73, 1.92
## 5.00 | 1.93 | 1.86, 2.01
## 6.00 | 2.17 | 2.10, 2.25
## 6.50 | 2.30 | 2.21, 2.40
## 7.00 | 2.44 | 2.32, 2.57
## 8.00 | 2.74 | 2.54, 2.97
##
## Adjusted for:
## * trialNum = 4.50
## * sokobanonline__solve_rate = 0.73
## * participantEffort = 4.80
## * attempt_nRestart = 3.76
## * subject_id = 0 (population-level)
##
## attr(,"class")
## [1] "ggalleffects" "list"
## attr(,"model.name")
## [1] "."
df.analysis %>%
mutate(trialNum = case_when(trialNum > 4 ~ "Last half of puzzles",
trialNum <= 4 ~ "First half of puzzles"),
puzzle_id_sorted = fct_reorder(puzzle_id_sorted,
solved,
.fun = mean, .na_rm = TRUE)) %>%
filter(!is.na(trialNum)) %>%
ggplot(aes(x = puzzle_id_sorted,
y = solveDuration,
color = trialNum)) +
stat_summary(fun.data = mean_cl_boot,
geom = "pointrange",
position = position_dodge(.8)) +
geom_point(position = position_jitter(width = .1,
height = .1),
size = 2,
alpha = .1) +
scale_y_continuous(limits = c(0, 300),
breaks = seq(0,300,60)) +
labs(x = "Puzzle name",
y = "# of boxes solved (0-3)",
title = "# of boxes solved over time (first vs last half of puzzle set)",
subtitle = "8 puzzles per set",
color = "Stage") +
coord_flip()When broken down by puzzle:
df.analysis %>%
group_by(trialNum, puzzle_id_sorted) %>%
summarise(mean = mean(solveDuration, na.rm = T)) %>%
ggplot(aes(x = trialNum,
y = mean,
color = puzzle_id_sorted)) +
geom_point(position = position_jitter(width = .1,
height = .1),
size = 2,
alpha = .4) +
labs(x = "Puzzle order (1 through 8)",
y = "Mean solve time",
title = "Mean solve time over time",
fill = "Puzzle") +
theme(legend.position = "none") +
scale_x_continuous(breaks = seq(1,8,1)) +
scale_y_continuous(limits = c(0,300),
breaks = seq(0,300,60))Fitting the mixed effects model:
# mixed effects model
lm.duration_order =
glmer(solveDuration ~
1 +
# fixed effect for puzzle order (controlling for difficulty)
trialNum +
# controlling for other variables
sokobanonline__solve_rate + # difficulty
participantEffort + # subjective effort
attempt_nRestart + # no of attempts
mean_enjoyable + # sampled enjoyment ratings
# random intercept for player
(1 | subject_id),
family = poisson(link = "log"),
data = df.analysis)
# summary
lm.duration_order %>%
summary()## Generalized linear mixed model fit by maximum likelihood (Laplace
## Approximation) [glmerMod]
## Family: poisson ( log )
## Formula:
## solveDuration ~ 1 + trialNum + sokobanonline__solve_rate + participantEffort +
## attempt_nRestart + mean_enjoyable + (1 | subject_id)
## Data: df.analysis
##
## AIC BIC logLik deviance df.resid
## 12964.6 12995.4 -6475.3 12950.6 587
##
## Scaled residuals:
## Min 1Q Median 3Q Max
## -9.3608 -2.5398 -0.1669 2.1638 12.1721
##
## Random effects:
## Groups Name Variance Std.Dev.
## subject_id (Intercept) 0.1815 0.426
## Number of obs: 594, groups: subject_id, 170
##
## Fixed effects:
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) 4.565125 0.309418 14.754 < 2e-16 ***
## trialNum 0.040476 0.001880 21.531 < 2e-16 ***
## sokobanonline__solve_rate -0.040827 0.063534 -0.643 0.52048
## participantEffort 0.165448 0.063269 2.615 0.00892 **
## attempt_nRestart 0.145349 0.002033 71.502 < 2e-16 ***
## mean_enjoyable -0.137998 0.004647 -29.698 < 2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Correlation of Fixed Effects:
## (Intr) trilNm skb___ prtcpE attm_R
## trialNum -0.022
## skbnnln__s_ -0.122 0.002
## prtcpntEffr -0.985 0.002 0.014
## attmpt_nRst -0.066 0.161 0.106 0.024
## mean_enjybl 0.000 -0.092 -0.516 -0.013 0.065
## optimizer (Nelder_Mead) convergence code: 0 (OK)
## Model failed to converge with max|grad| = 0.0027371 (tol = 0.002, component 1)
## $trialNum
## # Predicted counts of solveDuration
##
## trialNum | Predicted | 95% CI
## -------------------------------------
## 1 | 119.42 | 112.17, 127.96
## 2 | 124.35 | 116.87, 133.17
## 3 | 129.49 | 121.75, 138.62
## 4 | 134.83 | 126.80, 144.32
## 5 | 140.40 | 132.04, 150.28
## 6 | 146.20 | 137.46, 156.53
## 7 | 152.24 | 143.07, 163.06
## 8 | 158.53 | 148.88, 169.91
##
## Adjusted for:
## * sokobanonline__solve_rate = 0.76
## * participantEffort = 4.83
## * attempt_nRestart = 1.98
## * mean_enjoyable = 6.39
## * subject_id = 0 (population-level)
##
## $sokobanonline__solve_rate
## # Predicted counts of solveDuration
##
## sokobanonline__solve_rate | Predicted | 95% CI
## ------------------------------------------------------
## 0.60 | 137.96 | 129.34, 148.12
## 0.70 | 137.40 | 129.15, 147.13
## 0.80 | 136.84 | 128.67, 146.48
## 0.90 | 136.28 | 127.88, 146.19
##
## Adjusted for:
## * trialNum = 4.41
## * participantEffort = 4.83
## * attempt_nRestart = 1.98
## * mean_enjoyable = 6.39
## * subject_id = 0 (population-level)
##
## $participantEffort
## # Predicted counts of solveDuration
##
## participantEffort | Predicted | 95% CI
## ----------------------------------------------
## 1 | 72.77 | 45.33, 117.60
## 3 | 101.32 | 80.49, 128.37
## 4 | 119.55 | 106.45, 135.13
## 5 | 141.06 | 132.10, 151.61
##
## Adjusted for:
## * trialNum = 4.41
## * sokobanonline__solve_rate = 0.76
## * attempt_nRestart = 1.98
## * mean_enjoyable = 6.39
## * subject_id = 0 (population-level)
##
## $attempt_nRestart
## # Predicted counts of solveDuration
##
## attempt_nRestart | Predicted | 95% CI
## ---------------------------------------------
## 0 | 102.82 | 96.63, 110.12
## 2 | 137.50 | 129.31, 147.17
## 3 | 159.01 | 149.54, 170.20
## 5 | 212.66 | 199.83, 227.79
## 7 | 284.40 | 266.79, 305.17
## 8 | 328.90 | 308.16, 353.33
## 10 | 439.85 | 410.89, 473.95
## 13 | 680.27 | 631.79, 737.27
##
## Adjusted for:
## * trialNum = 4.41
## * sokobanonline__solve_rate = 0.76
## * participantEffort = 4.83
## * mean_enjoyable = 6.39
## * subject_id = 0 (population-level)
##
## $mean_enjoyable
## # Predicted counts of solveDuration
##
## mean_enjoyable | Predicted | 95% CI
## -------------------------------------------
## 4.00 | 190.53 | 178.57, 204.61
## 4.40 | 180.29 | 169.16, 193.42
## 5.00 | 165.97 | 155.91, 177.84
## 5.40 | 157.05 | 147.62, 168.19
## 5.80 | 148.62 | 139.74, 159.10
## 6.40 | 136.81 | 128.66, 146.43
## 6.80 | 129.46 | 121.74, 138.58
## 7.80 | 112.78 | 105.91, 120.87
##
## Adjusted for:
## * trialNum = 4.41
## * sokobanonline__solve_rate = 0.76
## * participantEffort = 4.83
## * attempt_nRestart = 1.98
## * subject_id = 0 (population-level)
##
## attr(,"class")
## [1] "ggalleffects" "list"
## attr(,"model.name")
## [1] "."
df.analysis %>%
mutate(trialNum = case_when(trialNum > 4 ~ "Last half of puzzles",
trialNum <= 4 ~ "First half of puzzles"),
puzzle_id_sorted = fct_reorder(puzzle_id_sorted,
solved,
.fun = mean, .na_rm = TRUE)) %>%
filter(!is.na(trialNum)) %>%
ggplot(aes(x = puzzle_id_sorted,
y = attempt_nInputEvents,
color = trialNum)) +
stat_summary(fun.data = mean_cl_boot,
geom = "pointrange",
position = position_dodge(.8)) +
geom_point(position = position_jitter(width = .1,
height = .1),
size = 2,
alpha = .1) +
labs(x = "Puzzle name",
y = "# of moves",
title = "# of moves over time (first vs last half of puzzle set)",
subtitle = "8 puzzles per set",
color = "Stage") +
coord_flip()When broken down by puzzle:
df.analysis %>%
group_by(trialNum, puzzle_id_sorted) %>%
summarise(mean = mean(attempt_nInputEvents, na.rm = T)) %>%
ggplot(aes(x = trialNum,
y = mean,
color = puzzle_id_sorted)) +
geom_point(position = position_jitter(width = .1,
height = .1),
size = 2,
alpha = .4) +
labs(x = "Puzzle order (1 through 8)",
y = "Mean # of moves",
title = "Mean # of moves over time",
fill = "Puzzle") +
theme(legend.position = "none") +
scale_x_continuous(breaks = seq(1,8,1)) +
scale_y_continuous(limits = c(0, 600),
breaks = seq(0,600,100))Fitting the mixed effects model:
# mixed effects model
lm.moves_order =
glmer(attempt_nInputEvents ~
1 +
# fixed effect for puzzle order (controlling for difficulty)
trialNum +
# controlling for other variables
scale(sokobanonline__solve_rate) + # difficulty
scale(participantEffort) + # subjective effort
scale(attempt_nRestart) + # no of attempts
scale(mean_enjoyable) + # sampled enjoyment ratings
# random intercept for player
(1 | subject_id),
family = poisson(link = "log"),
data = df.analysis)
# summary
lm.moves_order %>%
summary()## Generalized linear mixed model fit by maximum likelihood (Laplace
## Approximation) [glmerMod]
## Family: poisson ( log )
## Formula:
## attempt_nInputEvents ~ 1 + trialNum + scale(sokobanonline__solve_rate) +
## scale(participantEffort) + scale(attempt_nRestart) + scale(mean_enjoyable) +
## (1 | subject_id)
## Data: df.analysis
##
## AIC BIC logLik deviance df.resid
## 50770.1 50807.9 -25378.1 50756.1 1633
##
## Scaled residuals:
## Min 1Q Median 3Q Max
## -13.2862 -3.4381 -0.3989 3.1754 21.8264
##
## Random effects:
## Groups Name Variance Std.Dev.
## subject_id (Intercept) 0.1335 0.3654
## Number of obs: 1640, groups: subject_id, 205
##
## Fixed effects:
## Estimate Std. Error z value
## (Intercept) 5.1087677 0.0258687 197.488
## trialNum -0.0132728 0.0008333 -15.928
## scale(sokobanonline__solve_rate) -0.0764573 0.0024735 -30.910
## scale(participantEffort) -0.0404824 0.0255909 -1.582
## scale(attempt_nRestart) 0.2341045 0.0023987 97.595
## scale(mean_enjoyable) -0.0418659 0.0028627 -14.625
## Pr(>|z|)
## (Intercept) <2e-16 ***
## trialNum <2e-16 ***
## scale(sokobanonline__solve_rate) <2e-16 ***
## scale(participantEffort) 0.114
## scale(attempt_nRestart) <2e-16 ***
## scale(mean_enjoyable) <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Correlation of Fixed Effects:
## (Intr) trilNm s(___) scl(E) sc(_R)
## trialNum -0.142
## scl(skb___) 0.037 -0.228
## scl(prtcpE) 0.000 0.000 0.002
## scl(ttmp_R) -0.024 0.102 -0.026 0.009
## scl(mn_njy) -0.020 0.159 -0.581 0.000 0.310
## optimizer (Nelder_Mead) convergence code: 0 (OK)
## Model is nearly unidentifiable: very large eigenvalue
## - Rescale variables?
## $trialNum
## # Predicted counts of attempt_nInputEvents
##
## trialNum | Predicted | 95% CI
## -------------------------------------
## 1 | 163.74 | 156.11, 172.70
## 2 | 161.58 | 154.08, 170.40
## 3 | 159.45 | 152.06, 168.14
## 4 | 157.35 | 150.07, 165.91
## 5 | 155.27 | 148.09, 163.72
## 6 | 153.23 | 146.13, 161.57
## 7 | 151.21 | 144.18, 159.46
## 8 | 149.21 | 142.26, 157.38
##
## Adjusted for:
## * sokobanonline__solve_rate = 0.73
## * participantEffort = 4.80
## * attempt_nRestart = 3.76
## * mean_enjoyable = 5.57
## * subject_id = 0 (population-level)
##
## $sokobanonline__solve_rate
## # Predicted counts of attempt_nInputEvents
##
## sokobanonline__solve_rate | Predicted | 95% CI
## ------------------------------------------------------
## 0.40 | 216.77 | 205.90, 229.48
## 0.60 | 177.88 | 169.54, 187.67
## 0.80 | 145.96 | 139.18, 153.94
## 1.00 | 119.78 | 113.91, 126.65
##
## Adjusted for:
## * trialNum = 4.50
## * participantEffort = 4.80
## * attempt_nRestart = 3.76
## * mean_enjoyable = 5.57
## * subject_id = 0 (population-level)
##
## $participantEffort
## # Predicted counts of attempt_nInputEvents
##
## participantEffort | Predicted | 95% CI
## ----------------------------------------------
## 1 | 210.89 | 145.43, 307.52
## 3 | 180.17 | 150.46, 216.96
## 4 | 166.53 | 152.14, 183.30
## 5 | 153.93 | 146.29, 162.87
##
## Adjusted for:
## * trialNum = 4.50
## * sokobanonline__solve_rate = 0.73
## * attempt_nRestart = 3.76
## * mean_enjoyable = 5.57
## * subject_id = 0 (population-level)
##
## $attempt_nRestart
## # Predicted counts of attempt_nInputEvents
##
## attempt_nRestart | Predicted | 95% CI
## ---------------------------------------------
## 0.00 | 122.03 | 116.35, 128.71
## 3.00 | 148.70 | 141.82, 156.79
## 6.00 | 181.20 | 172.80, 191.06
## 9.00 | 220.79 | 210.48, 232.90
## 11.00 | 251.88 | 240.03, 265.80
## 14.00 | 306.92 | 292.23, 324.16
## 17.00 | 373.99 | 355.68, 395.45
## 23.00 | 555.30 | 526.50, 588.94
##
## Adjusted for:
## * trialNum = 4.50
## * sokobanonline__solve_rate = 0.73
## * participantEffort = 4.80
## * mean_enjoyable = 5.57
## * subject_id = 0 (population-level)
##
## $mean_enjoyable
## # Predicted counts of attempt_nInputEvents
##
## mean_enjoyable | Predicted | 95% CI
## -------------------------------------------
## 3.50 | 167.18 | 159.32, 176.42
## 4.00 | 164.48 | 156.80, 173.51
## 4.50 | 161.83 | 154.31, 170.67
## 5.00 | 159.22 | 151.84, 167.89
## 6.00 | 154.12 | 146.98, 162.51
## 6.50 | 151.63 | 144.59, 159.91
## 7.00 | 149.19 | 142.22, 157.37
## 8.00 | 144.41 | 137.57, 152.44
##
## Adjusted for:
## * trialNum = 4.50
## * sokobanonline__solve_rate = 0.73
## * participantEffort = 4.80
## * attempt_nRestart = 3.76
## * subject_id = 0 (population-level)
##
## attr(,"class")
## [1] "ggalleffects" "list"
## attr(,"model.name")
## [1] "."
Is past performance a good predictor of future performance?
df.analysis =
df.analysis %>%
mutate(prev_puzzle_solved = lag(solved))
df.analysis %>%
mutate(puzzle_id_sorted = fct_reorder(puzzle_id_sorted,
solved,
.fun = mean, .na_rm = TRUE),
prev_puzzle_solved = case_when(prev_puzzle_solved == 1 ~ "Yes",
prev_puzzle_solved == 0 ~ "No")) %>%
filter(!is.na(prev_puzzle_solved)) %>%
ggplot(aes(x = puzzle_id_sorted,
y = (solved * 100),
fill = factor(prev_puzzle_solved))) +
stat_summary(fun = mean,
geom = "bar",
width = .6,
alpha = .5,
position = position_dodge(.8)) +
stat_summary(fun.data = mean_cl_boot,
geom = "errorbar",
position = position_dodge(.8)) +
scale_fill_manual(values = c("Yes" = "darkgreen",
"No" = "darkred")) +
labs(x = "Puzzle name",
y = "% solved",
fill = "Last puzzle solved?",
title = "% solved by previous puzzle success",
subtitle = "N = 205 subjects, 24 puzzles total (n = 67-70 each)") +
coord_flip() +
theme(legend.position = "right")Fitting the mixed effects model:
# mixed effects model
lm.previous_performance =
glmer(solved ~
1 +
# fixed effect for previous puzzle solved
prev_puzzle_solved +
# controlling for other variables
scale(sokobanonline__solve_rate) + # difficulty
scale(participantEffort) + # subjective effort
scale(attempt_nRestart) + # no of attempts
# random intercept for player
(1 | subject_id),
family = poisson(link = "log"),
data = df.analysis)
# summary
lm.previous_performance %>%
summary()## Generalized linear mixed model fit by maximum likelihood (Laplace
## Approximation) [glmerMod]
## Family: poisson ( log )
## Formula:
## solved ~ 1 + prev_puzzle_solved + scale(sokobanonline__solve_rate) +
## scale(participantEffort) + scale(attempt_nRestart) + (1 |
## subject_id)
## Data: df.analysis
##
## AIC BIC logLik deviance df.resid
## 2133.3 2165.7 -1060.7 2121.3 1633
##
## Scaled residuals:
## Min 1Q Median 3Q Max
## -0.9832 -0.4917 -0.3317 0.3886 4.7142
##
## Random effects:
## Groups Name Variance Std.Dev.
## subject_id (Intercept) 0.1745 0.4177
## Number of obs: 1639, groups: subject_id, 205
##
## Fixed effects:
## Estimate Std. Error z value
## (Intercept) -1.456309 0.073308 -19.865
## prev_puzzle_solved 0.259869 0.088379 2.940
## scale(sokobanonline__solve_rate) 0.237241 0.041138 5.767
## scale(participantEffort) -0.008423 0.052765 -0.160
## scale(attempt_nRestart) -0.751607 0.070664 -10.636
## Pr(>|z|)
## (Intercept) < 2e-16 ***
## prev_puzzle_solved 0.00328 **
## scale(sokobanonline__solve_rate) 8.07e-09 ***
## scale(participantEffort) 0.87318
## scale(attempt_nRestart) < 2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Correlation of Fixed Effects:
## (Intr) prv_p_ s(___) scl(E)
## prv_pzzl_sl -0.430
## scl(skb___) -0.109 0.084
## scl(prtcpE) 0.018 -0.026 0.010
## scl(ttmp_R) 0.400 0.107 0.219 0.058
## $prev_puzzle_solved
## # Predicted counts of solved
##
## prev_puzzle_solved | Predicted | 95% CI
## -------------------------------------------
## 0 | 0.39 | 0.56, 0.74
## 1 | 0.50 | 0.71, 0.98
##
## Adjusted for:
## * sokobanonline__solve_rate = 0.73
## * participantEffort = 4.80
## * attempt_nRestart = 3.76
## * subject_id = 0 (population-level)
##
## $sokobanonline__solve_rate
## # Predicted counts of solved
##
## sokobanonline__solve_rate | Predicted | 95% CI
## --------------------------------------------------
## 0.40 | 0.15 | 0.17, 0.38
## 0.60 | 0.28 | 0.39, 0.58
## 0.80 | 0.53 | 0.77, 1.00
## 1.00 | 0.97 | 1.21, 2.16
##
## Adjusted for:
## * prev_puzzle_solved = 0.36
## * participantEffort = 4.80
## * attempt_nRestart = 3.76
## * subject_id = 0 (population-level)
##
## $participantEffort
## # Predicted counts of solved
##
## participantEffort | Predicted | 95% CI
## ------------------------------------------
## 1 | 0.45 | 0.34, 1.64
## 3 | 0.44 | 0.50, 1.07
## 4 | 0.43 | 0.58, 0.88
## 5 | 0.42 | 0.62, 0.80
##
## Adjusted for:
## * prev_puzzle_solved = 0.36
## * sokobanonline__solve_rate = 0.73
## * attempt_nRestart = 3.76
## * subject_id = 0 (population-level)
##
## $attempt_nRestart
## # Predicted counts of solved
##
## attempt_nRestart | Predicted | 95% CI
## -----------------------------------------
## 0.00 | 0.94 | 1.36, 1.80
## 3.00 | 0.50 | 0.74, 0.93
## 6.00 | 0.26 | 0.37, 0.53
## 9.00 | 0.14 | 0.18, 0.31
## 11.00 | 0.09 | 0.11, 0.22
## 14.00 | 0.05 | 0.05, 0.13
## 17.00 | 0.03 | 0.02, 0.08
## 23.00 | 0.01 | 0.01, 0.03
##
## Adjusted for:
## * prev_puzzle_solved = 0.36
## * sokobanonline__solve_rate = 0.73
## * participantEffort = 4.80
## * subject_id = 0 (population-level)
##
## attr(,"class")
## [1] "ggalleffects" "list"
## attr(,"model.name")
## [1] "."
% solved:
# null model: no learning over time
lm.solve_growth_null =
glmer(solved ~
1 +
# control vars
scale(astar_solution_length) +
scale(sokobanonline__solve_rate) +
(1 | puzzle_id_sorted) +
(1 + trialNum | subject_id), # random slopes and intercepts per subject
data = df.analysis,
family = binomial(link = "logit"),
control = glmerControl(optimizer = "bobyqa"))
lm.solve_growth =
glmer(solved ~
1 +
# fixed effect
trialNum +
# control vars
scale(astar_solution_length) +
scale(sokobanonline__solve_rate) +
(1 | puzzle_id_sorted) + # random slope for puzzle
(1 + trialNum | subject_id), # random slopes and intercepts per subject
data = df.analysis,
family = binomial(link = "logit"),
control = glmerControl(optimizer = "bobyqa"))
lm.solve_growth %>%
summary()## Generalized linear mixed model fit by maximum likelihood (Laplace
## Approximation) [glmerMod]
## Family: binomial ( logit )
## Formula:
## solved ~ 1 + trialNum + scale(astar_solution_length) + scale(sokobanonline__solve_rate) +
## (1 | puzzle_id_sorted) + (1 + trialNum | subject_id)
## Data: df.analysis
## Control: glmerControl(optimizer = "bobyqa")
##
## AIC BIC logLik deviance df.resid
## 1534.5 1577.7 -759.2 1518.5 1632
##
## Scaled residuals:
## Min 1Q Median 3Q Max
## -4.2814 -0.4325 -0.1487 0.4017 7.7285
##
## Random effects:
## Groups Name Variance Std.Dev. Corr
## subject_id (Intercept) 1.919467 1.38545
## trialNum 0.008961 0.09466 1.00
## puzzle_id_sorted (Intercept) 2.331166 1.52682
## Number of obs: 1640, groups: subject_id, 205; puzzle_id_sorted, 24
##
## Fixed effects:
## Estimate Std. Error z value
## (Intercept) -1.1882399 0.0009211 -1289.964
## trialNum -0.0078792 0.0009242 -8.526
## scale(astar_solution_length) -0.8155390 0.0009212 -885.281
## scale(sokobanonline__solve_rate) 0.9974857 0.0009212 1082.787
## Pr(>|z|)
## (Intercept) <2e-16 ***
## trialNum <2e-16 ***
## scale(astar_solution_length) <2e-16 ***
## scale(sokobanonline__solve_rate) <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Correlation of Fixed Effects:
## (Intr) trilNm sc(__)
## trialNum 0.000
## scl(str_s_) 0.000 0.000
## scl(skb___) 0.000 0.000 0.000
## optimizer (bobyqa) convergence code: 0 (OK)
## Model failed to converge with max|grad| = 0.0770368 (tol = 0.002, component 1)
## Model is nearly unidentifiable: very large eigenvalue
## - Rescale variables?
## Data: df.analysis
## Models:
## lm.solve_growth_null: solved ~ 1 + scale(astar_solution_length) + scale(sokobanonline__solve_rate) + (1 | puzzle_id_sorted) + (1 + trialNum | subject_id)
## lm.solve_growth: solved ~ 1 + trialNum + scale(astar_solution_length) + scale(sokobanonline__solve_rate) + (1 | puzzle_id_sorted) + (1 + trialNum | subject_id)
## npar AIC BIC logLik deviance Chisq Df
## lm.solve_growth_null 7 1532.5 1570.3 -759.25 1518.5
## lm.solve_growth 8 1534.5 1577.7 -759.24 1518.5 0.0184 1
## Pr(>Chisq)
## lm.solve_growth_null
## lm.solve_growth 0.892
df.analysis$predicted_solve =
predict(lm.solve_growth, type = "response")
df.analysis_subject =
df.analysis %>%
group_by(subject_id, trialNum) %>%
summarise(mean_pred = mean(predicted_solve, na.rm = TRUE),
.groups = "drop")
df.analysis_subject %>%
ggplot(aes(x = trialNum,
y = (mean_pred*100))) +
geom_line(aes(group = subject_id),
alpha = 0.1, color = "gray") + # individual trajectories
stat_summary(fun = mean,
geom = "line",
size = 1,
color = "#1f77b4") + # average curve
stat_summary(fun.data = mean_cl_boot,
geom = "ribbon",
aes(group = 1),
fill = "#1f77b4",
alpha = 0.2) +
labs(x = "Puzzle #",
y = "% solved",
title = "Predicted performance curves across puzzles: % solved",
subtitle = "Grey lines are individual subjects, blue line and ribbon equal predicted mean + 95% CI") +
scale_x_continuous(limits = c(1, 8),
breaks = seq(1,8,1)) +
theme_minimal()boxes solved:
# null model: no learning over time
lm.boxes_growth_null =
glmer(boxesSolved ~
1 +
# control vars
scale(astar_solution_length) +
scale(sokobanonline__solve_rate) +
(1 | puzzle_id_sorted) + # random slope for puzzle
(1 + trialNum | subject_id), # random slopes and intercepts per subject
data = df.analysis,
family = poisson(link = "log"),
control = glmerControl(optimizer = "bobyqa"))# full model:
lm.boxes_growth =
glmer(boxesSolved ~
1 +
trialNum +
# control vars
scale(astar_solution_length) +
scale(sokobanonline__solve_rate) +
(1 | puzzle_id_sorted) + # random slope for puzzle
(1 + trialNum | subject_id), # random slopes and intercepts per subject
data = df.analysis,
family = poisson(link = "log"),
control = glmerControl(optimizer = "bobyqa"))
lm.boxes_growth %>%
summary()## Generalized linear mixed model fit by maximum likelihood (Laplace
## Approximation) [glmerMod]
## Family: poisson ( log )
## Formula:
## boxesSolved ~ 1 + trialNum + scale(astar_solution_length) + scale(sokobanonline__solve_rate) +
## (1 | puzzle_id_sorted) + (1 + trialNum | subject_id)
## Data: df.analysis
## Control: glmerControl(optimizer = "bobyqa")
##
## AIC BIC logLik deviance df.resid
## 4750.5 4793.8 -2367.3 4734.5 1632
##
## Scaled residuals:
## Min 1Q Median 3Q Max
## -1.58271 -0.24067 0.01022 0.38199 1.47835
##
## Random effects:
## Groups Name Variance Std.Dev. Corr
## subject_id (Intercept) 0.000e+00 0.000e+00
## trialNum 6.955e-15 8.340e-08 NaN
## puzzle_id_sorted (Intercept) 2.985e-02 1.728e-01
## Number of obs: 1640, groups: subject_id, 205; puzzle_id_sorted, 24
##
## Fixed effects:
## Estimate Std. Error z value
## (Intercept) 0.7148071 0.0568420 12.575
## trialNum 0.0007999 0.0091031 0.088
## scale(astar_solution_length) -0.1192187 0.0421645 -2.827
## scale(sokobanonline__solve_rate) 0.0600862 0.0409598 1.467
## Pr(>|z|)
## (Intercept) < 2e-16 ***
## trialNum 0.92998
## scale(astar_solution_length) 0.00469 **
## scale(sokobanonline__solve_rate) 0.14239
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Correlation of Fixed Effects:
## (Intr) trilNm sc(__)
## trialNum -0.721
## scl(str_s_) 0.182 -0.227
## scl(skb___) 0.085 -0.130 0.262
## optimizer (bobyqa) convergence code: 0 (OK)
## boundary (singular) fit: see help('isSingular')
## Data: df.analysis
## Models:
## lm.boxes_growth_null: boxesSolved ~ 1 + scale(astar_solution_length) + scale(sokobanonline__solve_rate) + (1 | puzzle_id_sorted) + (1 + trialNum | subject_id)
## lm.boxes_growth: boxesSolved ~ 1 + trialNum + scale(astar_solution_length) + scale(sokobanonline__solve_rate) + (1 | puzzle_id_sorted) + (1 + trialNum | subject_id)
## npar AIC BIC logLik deviance Chisq Df
## lm.boxes_growth_null 7 4748.5 4786.4 -2367.3 4734.5
## lm.boxes_growth 8 4750.5 4793.8 -2367.3 4734.5 0.0077 1
## Pr(>Chisq)
## lm.boxes_growth_null
## lm.boxes_growth 0.93
df.analysis$predicted_boxes =
predict(lm.boxes_growth, type = "response")
df.analysis_subject =
df.analysis %>%
group_by(subject_id, trialNum) %>%
summarise(mean_pred = mean(predicted_boxes, na.rm = TRUE),
.groups = "drop")
df.analysis_subject %>%
ggplot(aes(x = trialNum,
y = mean_pred)) +
geom_line(aes(group = subject_id),
alpha = 0.1, color = "gray") + # individual trajectories
stat_summary(fun = mean,
geom = "line",
size = 1,
color = "#1f77b4") + # average curve
stat_summary(fun = "errorbar",
geom = "line",
size = 1,
color = "#1f77b4") + # average curve
stat_summary(fun.data = mean_cl_boot,
geom = "ribbon",
aes(group = 1),
fill = "#1f77b4",
alpha = 0.2) +
labs(x = "Puzzle #",
y = "# of boxes solved",
title = "Predicted performance curves across puzzles: # of boxes solved",
subtitle = "Grey lines are individual subjects, blue line and ribbon equal predicted mean + 95% CI") +
scale_x_continuous(limits = c(1, 8),
breaks = seq(1,8,1)) +
scale_y_continuous(limits = c(0, 3),
breaks = seq(0,3, 1)) +
theme_minimal()time to solution:
# null model: no learning over time
lm.time_growth_null =
glmer(solveDuration ~
1 +
# control vars
scale(astar_solution_length) +
scale(sokobanonline__solve_rate) +
(1 | puzzle_id_sorted) + # random slope for puzzle
(1 + trialNum | subject_id), # random slopes and intercepts per subject
data = df.analysis,
family = poisson(link = "log"),
control = glmerControl(optimizer = "bobyqa"))# full model:
lm.time_growth =
glmer(solveDuration ~
1 +
trialNum +
# control vars
scale(astar_solution_length) +
scale(sokobanonline__solve_rate) +
(1 | puzzle_id_sorted) + # random slope for puzzle
(1 + trialNum | subject_id), # random slopes and intercepts per subject
data = df.analysis,
family = poisson(link = "log"),
control = glmerControl(optimizer = "bobyqa"))
lm.time_growth %>%
summary()## Generalized linear mixed model fit by maximum likelihood (Laplace
## Approximation) [glmerMod]
## Family: poisson ( log )
## Formula:
## solveDuration ~ 1 + trialNum + scale(astar_solution_length) +
## scale(sokobanonline__solve_rate) + (1 | puzzle_id_sorted) +
## (1 + trialNum | subject_id)
## Data: df.analysis
## Control: glmerControl(optimizer = "bobyqa")
##
## AIC BIC logLik deviance df.resid
## 13086.4 13121.5 -6535.2 13070.4 586
##
## Scaled residuals:
## Min 1Q Median 3Q Max
## -9.7288 -2.2713 -0.0644 1.6028 12.9155
##
## Random effects:
## Groups Name Variance Std.Dev. Corr
## subject_id (Intercept) 0.83419 0.9133
## trialNum 0.03509 0.1873 -0.87
## puzzle_id_sorted (Intercept) 0.07271 0.2697
## Number of obs: 594, groups: subject_id, 170; puzzle_id_sorted, 23
##
## Fixed effects:
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) 5.26628 0.09455 55.700 < 2e-16
## trialNum -0.04062 0.01589 -2.556 0.01057
## scale(astar_solution_length) 0.16312 0.05952 2.741 0.00613
## scale(sokobanonline__solve_rate) -0.09956 0.06091 -1.635 0.10215
##
## (Intercept) ***
## trialNum *
## scale(astar_solution_length) **
## scale(sokobanonline__solve_rate)
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Correlation of Fixed Effects:
## (Intr) trilNm sc(__)
## trialNum -0.699
## scl(str_s_) 0.051 -0.014
## scl(skb___) -0.045 -0.008 0.143
## Data: df.analysis
## Models:
## lm.time_growth_null: solveDuration ~ 1 + scale(astar_solution_length) + scale(sokobanonline__solve_rate) + (1 | puzzle_id_sorted) + (1 + trialNum | subject_id)
## lm.time_growth: solveDuration ~ 1 + trialNum + scale(astar_solution_length) + scale(sokobanonline__solve_rate) + (1 | puzzle_id_sorted) + (1 + trialNum | subject_id)
## npar AIC BIC logLik deviance Chisq Df
## lm.time_growth_null 7 13091 13122 -6538.4 13077
## lm.time_growth 8 13086 13122 -6535.2 13070 6.48 1
## Pr(>Chisq)
## lm.time_growth_null
## lm.time_growth 0.01091 *
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
df.analysis =
df.analysis %>%
mutate(predicted_time = NA_real_)
df.analysis$predicted_time[df.analysis$solved == 1] =
predict(lm.time_growth, type = "response")
df.analysis_subject =
df.analysis %>%
group_by(subject_id, trialNum) %>%
summarise(mean_pred = mean(predicted_time, na.rm = TRUE),
.groups = "drop")
df.analysis_subject %>%
ggplot(aes(x = trialNum,
y = mean_pred)) +
geom_line(aes(group = subject_id),
alpha = 0.1, color = "gray") + # individual trajectories
stat_summary(fun = mean,
geom = "line",
size = 1,
color = "#1f77b4") + # average curve
stat_summary(fun = "errorbar",
geom = "line",
size = 1,
color = "#1f77b4") + # average curve
stat_summary(fun.data = mean_cl_boot,
geom = "ribbon",
aes(group = 1),
fill = "#1f77b4",
alpha = 0.2) +
labs(x = "Puzzle #",
y = "Time until solution",
title = "Predicted performance curves across puzzles: # of boxes solved",
subtitle = "Grey lines are individual subjects, blue line and ribbon equal predicted mean + 95% CI") +
scale_x_continuous(limits = c(1, 8),
breaks = seq(1,8,1)) +
scale_y_continuous(limits = c(0, 300),
breaks = seq(0, 300, 60)) +
theme_minimal()number of moves:
# null model: no learning over time
lm.moves_growth_null =
glmer(attempt_nInputEvents ~
1 +
# control vars
scale(astar_solution_length) +
scale(sokobanonline__solve_rate) +
(1 | puzzle_id_sorted) + # random slope for puzzle
(1 + trialNum | subject_id), # random slopes and intercepts per subject
data = df.analysis,
family = poisson(link = "log"),
control = glmerControl(optimizer = "bobyqa"))# full model:
lm.moves_growth =
glmer(attempt_nInputEvents ~
1 +
trialNum +
# control vars
scale(astar_solution_length) +
scale(sokobanonline__solve_rate) +
(1 | puzzle_id_sorted) + # random slope for puzzle
(1 + trialNum | subject_id), # random slopes and intercepts per subject
data = df.analysis,
family = poisson(link = "log"),
control = glmerControl(optimizer = "bobyqa"))
lm.moves_growth %>%
summary()## Generalized linear mixed model fit by maximum likelihood (Laplace
## Approximation) [glmerMod]
## Family: poisson ( log )
## Formula:
## attempt_nInputEvents ~ 1 + trialNum + scale(astar_solution_length) +
## scale(sokobanonline__solve_rate) + (1 | puzzle_id_sorted) +
## (1 + trialNum | subject_id)
## Data: df.analysis
## Control: glmerControl(optimizer = "bobyqa")
##
## AIC BIC logLik deviance df.resid
## 44553.5 44596.7 -22268.8 44537.5 1632
##
## Scaled residuals:
## Min 1Q Median 3Q Max
## -14.8471 -2.8981 -0.1796 2.5329 21.2837
##
## Random effects:
## Groups Name Variance Std.Dev. Corr
## subject_id (Intercept) 0.278284 0.52753
## trialNum 0.007601 0.08718 -0.48
## puzzle_id_sorted (Intercept) 0.026888 0.16398
## Number of obs: 1640, groups: subject_id, 205; puzzle_id_sorted, 24
##
## Fixed effects:
## Estimate Std. Error z value
## (Intercept) 5.263749 0.050075 105.118
## trialNum -0.053067 0.006199 -8.561
## scale(astar_solution_length) 0.113277 0.034737 3.261
## scale(sokobanonline__solve_rate) -0.106784 0.034817 -3.067
## Pr(>|z|)
## (Intercept) < 2e-16 ***
## trialNum < 2e-16 ***
## scale(astar_solution_length) 0.00111 **
## scale(sokobanonline__solve_rate) 0.00216 **
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Correlation of Fixed Effects:
## (Intr) trilNm sc(__)
## trialNum -0.363
## scl(str_s_) 0.004 -0.007
## scl(skb___) 0.002 -0.004 0.245
## Data: df.analysis
## Models:
## lm.moves_growth_null: attempt_nInputEvents ~ 1 + scale(astar_solution_length) + scale(sokobanonline__solve_rate) + (1 | puzzle_id_sorted) + (1 + trialNum | subject_id)
## lm.moves_growth: attempt_nInputEvents ~ 1 + trialNum + scale(astar_solution_length) + scale(sokobanonline__solve_rate) + (1 | puzzle_id_sorted) + (1 + trialNum | subject_id)
## npar AIC BIC logLik deviance Chisq Df
## lm.moves_growth_null 7 44614 44652 -22300 44600
## lm.moves_growth 8 44554 44597 -22269 44538 62.87 1
## Pr(>Chisq)
## lm.moves_growth_null
## lm.moves_growth 2.209e-15 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
df.analysis$predicted_moves =
predict(lm.moves_growth, type = "response")
df.analysis_subject =
df.analysis %>%
group_by(subject_id, trialNum) %>%
summarise(mean_pred = mean(predicted_moves, na.rm = TRUE),
.groups = "drop")
df.analysis_subject %>%
ggplot(aes(x = trialNum,
y = mean_pred)) +
geom_line(aes(group = subject_id),
alpha = 0.1, color = "gray") + # individual trajectories
stat_summary(fun = mean,
geom = "line",
size = 1,
color = "#1f77b4") + # average curve
stat_summary(fun = "errorbar",
geom = "line",
size = 1,
color = "#1f77b4") + # average curve
stat_summary(fun.data = mean_cl_boot,
geom = "ribbon",
aes(group = 1),
fill = "#1f77b4",
alpha = 0.2) +
labs(x = "Puzzle #",
y = "# of moves",
title = "Predicted performance curves across puzzles: # of moves solved",
subtitle = "Grey lines are individual subjects, blue line and ribbon equal predicted mean + 95% CI") +
scale_x_continuous(limits = c(1, 8),
breaks = seq(1,8,1)) +
scale_y_continuous(limits = c(0, 600),
breaks = seq(0, 600, 100)) +
theme_minimal()